﻿/**
* CRL
*/
using CRL.Data.LambdaQuery;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
namespace CRL.Data.DBExtend.RelationDB
{
    //返回动态类型
    public sealed partial class DBExtend
    {
        #region sql语句
        /// <summary>
        /// 返回dynamic集合
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="types"></param>
        /// <returns></returns>
        public override List<dynamic> ExecDynamicList(string sql)
        {
            var list = SqlStopWatch.ReturnData(() =>
            {
                return GetDataReader(sql);

            }, (r) =>
            {
                double runTime;
                return Dynamic.DynamicObjConvert.DataReaderToDynamic(r.reader, out runTime);
            });
            return list;
        }
        /// <summary>
        /// 返回dynamic集合
        /// </summary>
        /// <param name="sp"></param>
        /// <returns></returns>
        public override List<dynamic> RunDynamicList(string sp)
        {
            double runTime;
            //var reader = SqlStopWatch.RunDataReader(__DbHelper,sp);
            //ClearParame();
            //return Dynamic.DynamicObjConvert.DataReaderToDynamic(reader,out runTime);
            var list = SqlStopWatch.ReturnList(() =>
            {
                var db = GetDBHelper(DataAccessType.Read);
                var reader = db.RunDataReader(sp);
                return Dynamic.DynamicObjConvert.DataReaderToDynamic(reader, out runTime);
            }, sp);
            return list;
        }
        #endregion
        /// <summary>
        /// 返回动态对象
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public override List<dynamic> QueryDynamic(LambdaQueryBase query)
        {
            var list = SqlStopWatch.ReturnData(() =>
            {
                if (query.HasPageArgs())
                {
                    return GetPageReader(query);
                }
                return GetQueryDynamicReader(query);

            }, (r) =>
            {
                int count;
                var list2 = r.GetDataDynamic(out count);
                if (count == 0)
                {
                    count = list2.Count;
                }
                query.MapingTime += r.runTime;
                query.__RowCount = count;
                return list2;
            });
            return list;
        }
        

        /// <summary>
        /// 查询结果
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="query"></param>
        /// <param name="newExpression"></param>
        /// <returns></returns>
        public override List<TResult> QueryResult<TResult>(LambdaQueryBase query, NewExpression newExpression = null)
        {
            var anonymousClass = newExpression != null;
            List<TResult> list;
            var queryInfo = new LambdaQuery.Mapping.QueryInfo<TResult>(anonymousClass, query.GetQueryFieldString(), query.GetFieldMapping(), newExpression?.Constructor);
            queryInfo.__IncludeTypes = query.__IncludeTypes;
            int count = 0;
            list = SqlStopWatch.ReturnData(() =>
            {
                if (query.HasPageArgs())
                {
                    return GetPageReader(query);
                }
                else
                {
                    return GetQueryDynamicReader(query);
                }

            }, (r) =>
            {
                return r.GetDataTResult(queryInfo, out count);
            });
            if (count == 0)
            {
                count = list.Count;
            }
            query.__RowCount = count;
            return list;
        }
        public override void InvokeReaderCallback(LambdaQueryBase query, Action<IDataReader> readFunc)
        {
            CallBackDataReader callBackReader;
            if (query.HasPageArgs())
            {
                callBackReader = GetPageReader(query);
            }
            else
            {
                callBackReader = GetQueryDynamicReader(query);
            }
            using (var reader = callBackReader.reader)
            {
                while (reader.Read())
                {
                    readFunc(reader);
                }
            }
        }

        /// <summary>
        /// 返回首列结果
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <param name="iQuery"></param>
        /// <returns></returns>
        public override dynamic QueryScalar<TModel>(ILambdaQuery<TModel> iQuery)
        {
            var query = iQuery as LambdaQueryBase;
            query.TakeNum = 1;
            var list = SqlStopWatch.ReturnData(() =>
            {
                return GetQueryDynamicReader(query);

            }, (r) =>
            {
                using (var reader = r.reader)
                {
                    var a = reader.Read();
                    if (!a)
                    {
                        return null;
                    }
                    var result = reader[0];
                    if (result == DBNull.Value)
                    {
                        var columnType = query._CurrentSelectFieldCache.mapping.First().PropertyType;
                        result = System.Activator.CreateInstance(columnType);
                    }
                    reader.Close();
                    return new object[] { result };
                }
            });
            if (list == null)
            {
                return null;
            }
            return list.FirstOrDefault();
        }
        /// <summary>
        /// 返回动态对象的查询
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        internal CallBackDataReader GetQueryDynamicReader(LambdaQueryBase query)
        {
            CheckTableCreated(query.__MainType);
            var sql = "";
            query.FillParames(this);
            sql = query.GetQuery();
            sql = _DBAdapter.SqlFormat(sql);
            IDataReader reader;
            var compileSp = query.__CompileSp && _DBAdapter.CanCompileSP;
            var db = GetDBHelper(DataAccessType.Read);
            if (!compileSp)
            {
                if (query.TakeNum > 0)
                {
                    db.AutoFormatWithNolock = false;
                }
                reader = db.ExecDataReader(sql);
            }
            else//生成储过程
            {
                string sp = CompileSqlToSp(_DBAdapter.TemplateSp, sql);
                reader = db.RunDataReader(sp);
            }
            query.ExecuteTime = db.ExecuteTime;
            ClearParame();
            return new CallBackDataReader(reader, null, sql);
        }
    }
}
